﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using ClassLibraryEntidades;
using SmartDeviceClient.Negocio;
using System.Globalization;

namespace SmartDeviceClient.Interfaz
{
    public partial class FormOrigenDestino : Form
    {
        //###############################################################################
        //##########                    ATRIBUTOS Y PROPIEDADES                ##########
        //###############################################################################

        #region atributos y propiedades

            private Bitmap imagen;
            /// <summary>
            /// Mapa que se muestra.
            /// </summary>
            public Bitmap Imagen
            {
                set
                {
                    imagen = value;
                    CargaImagen(value);
                    

                }
            }

        #endregion



        //###############################################################################
        //##########                    CONSTRUCTORES                          ##########
        //###############################################################################

        public FormOrigenDestino()
        {
            InitializeComponent();
            

            if (!CompruebaConexion())
            {
                MessageBox.Show("El servidor no esta disponible. Se intentara conectar automaticamente.");
                this.timerReconectar.Enabled = true;
                return;
            }
            this.visorImagen.Imagen = new Bitmap(Program.GetAppPath() + @"Recursos\Cargando.png");
            MostrarMapa();
            
            //Program.posicionamiento.CerrarPuerto();
            //string[] posicion = Program.posicionamiento.DamePosicionString();
            //this.textBoxOrigen.Text = posicion[0];
            //this.textBoxDestino.Text = posicion[1];
        }

        public FormOrigenDestino(Bitmap imagen)
        {
            InitializeComponent();
            this.Imagen = imagen;
            
            //string[] posicion = Program.posicionamiento.DamePosicionString();
            //this.textBoxOrigen.Text = posicion[0];
            //this.textBoxDestino.Text = posicion[1];
        }
        


        //###############################################################################
        //##########                          MÉTODOS                          ##########
        //###############################################################################


        /// <summary>
        /// Se encarga de pedir el mapa al servicio web y mostrarlo en el visor.
        /// </summary>
        private void MostrarMapa()
        {
            //%%%%%%%%%%%%%%%%%%%%%%%% Version contra el servidor %%%%%%%%%%%%%%%%%%%%%%%%%
            //byte[] posicionserializada = Serializador.SerializarObjeto(new Coordenada());
            //byte[] received_binary = Program.proxy.DameMapa(posicionserializada); //Obtiene el mapa del servidor
            //Mapa mapa = (Mapa)Serializador.DeserializarObjeto(received_binary, typeof(Mapa)); //Deserializamos el mapa.
            //MemoryStream ms = new MemoryStream(mapa.imagen);
            //this.Imagen = new Bitmap(ms);   //Obtenemos la imagen del mapa.
            //ms.Close();


            //Para realizar una llamada asincrona al servidor
            AsyncCallback callBack = new AsyncCallback(MapaLlega);
            //Serializamos la coordenada que se le pasara en la llamada al servidor.
            byte[] posicionserializada = Serializador.SerializarObjeto(new Coordenada());
            //Llamada asincrona al servidor
            IAsyncResult asyncRes = Program.proxy.BeginDameMapa(posicionserializada, callBack, Program.proxy);
            

            
            //%%%%%%%%%%%%%%%%%%%%%%%% Version estatica. %%%%%%%%%%%%%%%%%%%%%%%%%
            //this.Imagen = new Bitmap(@"\My Documents\My Pictures\mapaCampusAlba.jpg");
        }

        private void MapaLlega(IAsyncResult asyncResult)
        {
            WebReference.Service myService = (WebReference.Service)asyncResult.AsyncState;
            byte[] received_binary = myService.EndDameMapa(asyncResult);
            //byte[] received_binary = Program.proxy.DameMapa(posicionserializada); //Obtiene el mapa del servidor
            Mapa mapa = (Mapa)Serializador.DeserializarObjeto(received_binary, typeof(Mapa)); //Deserializamos el mapa.
            MemoryStream ms = new MemoryStream(mapa.imagen);
            this.Imagen = new Bitmap(ms);   //Obtenemos la imagen del mapa.
            ms.Close();
        }

        public delegate void delegadoCargaImagen(Bitmap imagen);
        public void CargaImagen(Bitmap imagen)
        {
            if (visorImagen.InvokeRequired)
            {
                delegadoCargaImagen dlg = new delegadoCargaImagen(CargaImagen);
                visorImagen.Invoke(dlg, imagen);
            }
            else
            {
                this.visorImagen.Imagen = imagen;
                this.menuItemAceptar.Enabled = true;
            }
        }

        /// <summary>
        /// Comprueba si el servidor esta activo.
        /// </summary>
        /// <returns></returns>
        private bool CompruebaConexion()
        {
            try
            {
                Program.proxy.TestConexion();
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// Deja una calle con el puro nombre de la misma
        /// </summary>
        /// <param name="calle"></param>
        /// <returns></returns>
        private static string FormatearCalle(string calle)
        {
            calle = calle.ToLower();
            calle = calle.Replace(" ", String.Empty);
            calle = calle.Replace(".", String.Empty);
            calle = calle.Replace(",", String.Empty);
            calle = calle.Replace("calle", String.Empty);
            calle = calle.Replace("c/", String.Empty);
            calle = calle.Replace(@"c\", String.Empty);
            calle = calle.Replace("avenida", String.Empty);
            calle = calle.Replace("avda", String.Empty);
            calle = calle.Replace("av", String.Empty);
            calle = calle.Replace("carretera", String.Empty);
            calle = calle.Replace("crt", String.Empty);
            calle = calle.Replace("poligono", String.Empty);

            //------------Eliminación de acentos-------------------
            //String normalizedString = calle.Normalize(NormalizationForm.FormD);
            StringBuilder stringBuilder = new StringBuilder();

            for (int i = 0; i < calle.Length; i++)
            {
                Char c = calle[i];

                if (Char.IsPunctuation(c) || Char.IsSymbol(c) || char.IsNumber(c))
                    return null;

                if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                    stringBuilder.Append(c);

            }

            calle = stringBuilder.ToString();
            //-------------------------------------------------------

            return calle;

        }


        


        //###############################################################################
        //##########                          EVENTOS                          ##########
        //###############################################################################

        private void menuItemAceptar_Click(object sender, EventArgs e)
        {
            string textorigen = textBoxOrigen.Text;
            string textdestino = textBoxDestino.Text;

            if (textorigen == String.Empty ||
                textdestino == String.Empty ||
                textBoxNumeroOrigen.Text == String.Empty ||
                textBoxNumeroDestino.Text == String.Empty)
            {
                MessageBox.Show("Debe completar todos los campos de dirección");
                return;
            }
            try
            {
                Convert.ToInt32(textBoxNumeroOrigen.Text);
                Convert.ToInt32(textBoxNumeroDestino.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("El formato del número no es correcto");
                return;
            }

            textorigen = FormatearCalle(textorigen);
            textdestino = FormatearCalle(textdestino);
            if (textorigen == null || textdestino == null)
            {
                MessageBox.Show("El formato de alguna de las calles no es correcto");
                return;
            }

            //Encapsulamos las direciones en sus respectivos tipos para realizar más tarde la busqueda.
            Direccion origen = new Direccion(textorigen, Convert.ToInt32(textBoxNumeroOrigen.Text));
            Direccion destino = new Direccion(textdestino, Convert.ToInt32(textBoxNumeroDestino.Text));

            //Guardamos las direciones en la clase program.
            Program.busqueda = new BusquedaNatural(origen, destino);

            FormTipoRuta formularioTipoRuta = new FormTipoRuta(this.imagen);
            formularioTipoRuta.Show();
            this.Hide();
        }


        private void FormOrigenDestino_Closing(object sender, CancelEventArgs e)
        {
            Application.Exit();
        }

        private void menuItemCancelar_Click(object sender, EventArgs e)
        {
            FormLogin formularioLogin = new FormLogin();
            formularioLogin.Show();
            this.Hide();
        }

        private void timerReconectar_Tick(object sender, EventArgs e)
        {
            if (CompruebaConexion())
            {
                MostrarMapa();
                this.timerReconectar.Enabled = false;
                this.visorImagen.Imagen = new Bitmap(Program.GetAppPath() + @"Recursos\Cargando.png");
                MessageBox.Show("Hemos recuperado la conexión.");
            }
        }

        private void textBoxOrigen_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                menuItemAceptar_Click(null, null);
            }
        }

        private void textBoxDestino_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                menuItemAceptar_Click(null, null);
            }
        }

        private void textBoxNumeroOrigen_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                menuItemAceptar_Click(null, null);
            }
        }

        private void textBoxNumeroDestino_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                menuItemAceptar_Click(null, null);
            }
        }

        private void menuItemAyuda_Click(object sender, EventArgs e)
        {
            FormAyuda formularioAyuda = new FormAyuda();
            formularioAyuda.Informacion = Program.config.InformacionOrigenDestino;
            formularioAyuda.Show();
        }      

    }
}